package com.nulldev.util.concurrency.threadIt.v4.sched;

import java.util.concurrent.ExecutorService;

import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.concurrency.threadIt.v4.emapi.uft.Executable;
import com.nulldev.util.concurrency.threadIt.v4.emapi.uft.Returnable;

public interface ASyncScheduler extends Runnable {

	public static enum ASyncSchedulerDebugQuery {
		/* Queueing */

		ASYNC_SCHED_DEBUG_QUEUE_SIZE,

		/* Batching */

		ASYNC_SCHED_DEBUG_L1_BATCHING_ENABLED,
		ASYNC_SCHED_DEBUG_L2_BATCHING_ENABLED,
		ASYNC_SCHED_DEBUG_EXECUTOR_BATCHING_SUPPORTED,

		/* Optimizations */

		ASYNC_SCHED_DEBUG_L1_OPTIMIZATIONS_ENABLED,

	}

	public static final int MAXIMUM_BATCH_SIZE = 24;
	public static final int BATCH_SIZE = MathUtil.clamp(3, 8, Runtime.getRuntime().availableProcessors());

	public void submit_async(final Runnable r);

	public <T> Executable<T> submit_async(final Executable<T> r);

	public default <T> boolean attempt_async_submit(final Executable<T> r) {
		this.submit_async(r);
		return true;
	}

	public <T> Executable<T> submit_async(final Returnable<T> r);

	public void submit_all_async(final Runnable... r);

	public void clearQueues();

	public default void executorUpdated(final ExecutorService ex) {
	}

	public default boolean supportsDebugQuery() {
		return false;
	}

	public default Object debug_query(final ASyncSchedulerDebugQuery query) {
		return null;
	}
}
